/************************************************************************/
/*    Author: Scott Bevin                                               */
/************************************************************************/


#include "ComponentContainer.h"
#include "EntityComponent.h"
#include "EntityComponentFactory.h"

namespace XF
{
	ComponentContainer::ComponentContainer() : mComponentsInitialized(false)
	{
	}

	ComponentContainer::ComponentContainer(ComponentContainer &copy) : mComponentsInitialized(false)
	{
		for(unsigned int i = 0; i < copy.mComponents.size(); ++i)
		{
			EntityComponent* thisComp = copy.mComponents[i];

			EntityComponent* newComp = EntityComponentFactory::CreateComponent(thisComp->ComponentName(), (GameEntity*)this);

			newComp->CopyPropertys(thisComp);

			AddComponent(newComp);
		}
	}

	ComponentContainer::~ComponentContainer()
	{
		for(unsigned int i = 0; i < mComponents.size(); ++i)
		{
			EntityComponent* thisComp = mComponents[i];
			delete mComponents[i];
		}
	}

	void ComponentContainer::AddComponent(XF::EntityComponent *newComponent)
	{
		mComponents.push_back(newComponent);

		if(mComponentsInitialized)
			newComponent->Initialize();
	}

	void ComponentContainer::UpdateComponents(double dT)
	{
		std::list<int> killList;

		for(unsigned int i = 0; i < mComponents.size(); ++i)
		{
			EntityComponent* thisComp = mComponents[i];

			if(!thisComp->ShouldKill())
				thisComp->Update(dT);
			else
			{				
				mComponents[i] = mComponents[mComponents.size() - 1];

				mComponents.pop_back();

				delete thisComp;
			}
		}
	}

	void ComponentContainer::HandleInputComponents(double dT, XF::Input* input)
	{
		for(unsigned int i = 0; i < mComponents.size(); ++i)
		{
			EntityComponent* thisComp = mComponents[i];

			if(!thisComp->ShouldKill())
				thisComp->HandleInput(dT, input);
		}
	}

	bool ComponentContainer::MessageComponents(const XF::Message& message)
	{
		bool messageHandled = false;

		int size = (int)mComponents.size();

		for(int i = 0; i < size; ++i)
		{
			EntityComponent* thisComp = mComponents[i];

			if(!thisComp->ShouldKill())
				messageHandled = (thisComp->HandleMessage(message) || messageHandled); //this will make it return true if one returns true, which one do we really want??
		}

		return messageHandled;
	}

	void ComponentContainer::InitializeComponents()
	{
		mComponentsInitialized = true;

		for(unsigned int i = 0; i < mComponents.size(); ++i)
		{
			EntityComponent* thisComp = mComponents[i];

			thisComp->Initialize();
		}
	}
}